---
description: Компонент для создания поля ввода сообщений с поддержкой иконок действий.
---

<Overview group="forms">

# WriteBar [tag:component]

Компонент для создания поля ввода сообщений с поддержкой иконок действий.
Аналог строки ввода в мессенджерах и соцсетях. Принимает все свойства нативного `<textarea>`.

</Overview>

<Playground>
  ```jsx
  <WriteBar before={<WriteBarIcon mode="attach" />} placeholder="Введите сообщение..." />
  ```
</Playground>

## Режим работы

Компонент поддерживает работу как в неконтролируемом режиме, так и контролируемом. Это стандартное поведение
React-компонентов, прочитать про это можно в [документации React](https://react.dev/reference/react-dom/components/input#controlling-an-input-with-a-state-variable).

Для использования неконтролируемого режима достаточно просто _не_ передавать `value` или передавать `defaultValue`, если
требуется задать значение по умолчанию.
Для контролируемого режима используйте связку свойств `value`/`onChange` для задания значения и его изменения.

```jsx
// Неконтролируемое состояние
<WriteBar defaultValue="Текст" />;

// Контролируемое состояние
const [text, setText] = React.useState('Текст');

<WriteBar value={text} onChange={(event) => setText(event.target.value)} />;
```

## Основные элементы

- `before` — элементы слева от поля ввода.
- `after` — элементы справа.
- `inlineAfter` — элементы поверх поля (актуально для iOS).

<Playground>
  ```jsx
  <WriteBar
    before={<WriteBarIcon mode="attach" />}
    after={
      <WriteBarIcon label="Записать голосовое сообщение">
        <Icon24VoiceOutline />
      </WriteBarIcon>
    }
    inlineAfter={
      <WriteBarIcon label="Смайлы и стикеры">
        <Icon24SmileOutline />
      </WriteBarIcon>
    }
    placeholder="Введите сообщение..."
  />
  ```
</Playground>

## Использование иконок [#icons]

Все боковые элементы рекомендуется оборачивать в `WriteBarIcon`.
Также для адаптирования размеров иконок стоит использовать компонент [`AdaptiveIconRenderer`](/components/adaptive-icon-renderer).

По правилам дизайн-системы в `"regular"`-режиме используются кнопки размером `28px`, в `"compact"`-режиме — `24px`.
Исключение: на платформе `iOS` допускается использование иконок размером `28px` в `"compact"`-режиме.

<Playground style={{ width: 290 }}>

```jsx
const [text, setText] = React.useState('');
const platform = usePlatform();

const SmileOutlineIcon = (
  <AdaptiveIconRenderer
    IconCompact={platform === 'ios' ? Icon28SmileOutline : Icon24SmileOutline}
    IconRegular={Icon28SmileOutline}
  />
);

const VoiceOutlineIcon = (
  <AdaptiveIconRenderer
    IconCompact={platform === 'ios' ? Icon28VoiceOutline : Icon24VoiceOutline}
    IconRegular={Icon28VoiceOutline}
  />
);

const KeyboardBotsOutlineIcon = (
  <AdaptiveIconRenderer
    IconCompact={platform === 'ios' ? Icon28KeyboardBotsOutline : Icon24KeyboardBotsOutline}
    IconRegular={Icon28KeyboardBotsOutline}
  />
);

return (
  <WriteBar
    value={text}
    onChange={(e) => setText(e.target.value)}
    before={<WriteBarIcon mode="attach" />}
    inlineAfter={
      <>
        {text.length === 0 && (
          <WriteBarIcon label="Открыть меню бота">{KeyboardBotsOutlineIcon}</WriteBarIcon>
        )}
        {text.length > 0 && (
          <WriteBarIcon label="Эмоджи и стикеры">{SmileOutlineIcon}</WriteBarIcon>
        )}
      </>
    }
    after={
      <>
        {text.length === 0 && (
          <WriteBarIcon label="Эмоджи и стикеры">{SmileOutlineIcon}</WriteBarIcon>
        )}
        {text.length === 0 && (
          <WriteBarIcon label="Записать голосовое сообщение">{VoiceOutlineIcon}</WriteBarIcon>
        )}
        {text.length > 0 && <WriteBarIcon mode="send" />}
      </>
    }
    placeholder="Сообщение"
  />
);
```

</Playground>

## WriteBarIcon [tag:component]

Компонент для создания иконок-кнопок внутри `WriteBar`. Обеспечивает стандартное поведение и доступность
для элементов управления в поле ввода сообщений.

### Особенности поведения

- Наследует все свойства `<button>`.
- Автоматически адаптируется под платформы Android и iOS при использовании готовых пресетов.

### Предустановленные режимы

Предустановленные типы кнопок в `WriteBar` для отрисовки иконки и установки текста кнопки в зависимости от платформы.
Если передать валидное значение для этого свойства, `children` игнорируются,
а для `label` по умолчанию используется текст на "ru_RU".

- `attach` — иконка прикрепления с текстом "Прикрепить файл".
- `send` — иконка отправки с текстом "Отправить".
- `done` — иконка подтверждения с текстом "Готово".

<Playground>
  ```jsx
  <WriteBarIcon mode="attach" />
  <WriteBarIcon mode="send" />
  <WriteBarIcon mode="done" />
  ```
</Playground>

### Использование кастомных иконки

<Playground>

```jsx
const platform = usePlatform();

return (
  <WriteBarIcon label="Голосовое сообщение">
    <AdaptiveIconRenderer
      IconCompact={platform === 'ios' ? Icon28VoiceOutline : Icon24VoiceOutline}
      IconRegular={Icon28VoiceOutline}
    />
  </WriteBarIcon>
);
```

</Playground>

### Отображение счётчика

Значение счётчика для кнопки. Например, для количества прикреплённых файлов.

<Playground>
  ```jsx
  <WriteBarIcon mode="attach" count={3} label="Прикреплённые файлы" />
  ```
</Playground>

## Кастомизация

Компонент поддерживает свойство `slotProps`, которое даёт возможность прокинуть свойство в некоторые внутренние элементы.
Это удобно для добавления кастомных классов, data-атрибутов, aria-атрибутов, обработчиков событий, доступов к элементам через `getRootRef` и других расширений, не влияя на внешний API компонента.

<Playground style={{ maxWidth: 270 }}>
  ```jsx
  const textareaRef = React.useRef();

  return (
    <WriteBar
      before={<WriteBarIcon mode="attach" />}
      placeholder="Введите сообщение..."
      className="my-root-class"
      data-testid="write-bar-root"
      id="write-bar-textarea-id"
      slotProps={{
        root: {
          id: 'write-bar-root-id',
        },
        input: {
          className: 'my-textarea-class',
          'aria-label': 'Пример slotProps',
          getRootRef: textareaRef,
        },
      }}
    />
  )
  ```
</Playground>

### Доступность (a11y) [#a11y]

Укажите текстовое описание одним из способов:

- Через свойство `label`:

  ```jsx
  <WriteBarIcon label="Прикрепить файл">
    <Icon24Attachment />
  </WriteBarIcon>
  ```

- Через ARIA-атрибуты:

  ```jsx
  <WriteBarIcon aria-label="Отправить сообщение">
    <Icon24Send />
  </WriteBarIcon>
  ```

- С использованием VisuallyHidden:

  ```jsx
  <WriteBarIcon>
    <Icon24SmileOutline />
    <VisuallyHidden>Эмодзи</VisuallyHidden>
  </WriteBarIcon>
  ```

- С использованием `id` в `aria-labelledby`

  ```jsx
  <VisuallyHidden id="write_bar_icon_voice">Записать голосовое сообщение</VisuallyHidden>
    <WriteBarIcon aria-labelledby="write_bar_icon_voice">
    <Icon28VoiceOutline />
  </WriteBarIcon>
  ```

## Свойства и методы [#api]

<PropsTable name={["WriteBar", "WriteBarIcon"]}>
### WriteBar [#write-bar-api]

### WriteBarIcon [#write-bar-icon-api]

</PropsTable>
